package object_string_0920;

/**
 *  关于字符串常量池：
 *  1.存储一系列的字符串对象，当字符串常量第一次出现，且常量池中没有该值字符串对象，就会将该对象置入常量池。
 *  2.若采用直接赋值的方式申明字符串引用，若常量中存在该对象，则直接返回常量池的字符对象，不会创建新对象
 *  3.关于intern方法，尝试当前字符串对象置入常量池，若常量池没有该值，则将当前对象置入常量池。若常量池已经包含了该值的对象，则不会将对象置入常量池，intern方法直接返回常量池对应的对象
 *  ps:intern方法注意接收
 *
 * 只有字符串直接赋值时，才会用到字符串的常量池
 * 采用直接赋值类似String str =字符串字面量"的方式创建字符串对象，会使用字符串的常量池:
 * 若该对象是第一次使用，就在堆中开辟新空间，产生新对象，产生之后将该对象置入字符串的常量池
 * 当下次再次使用该对象时，若常量池中已有该内容的字符串，直接引用常量池中的对象。不再创建字符串。
 * “池化”思路
 * 节省内存，提高效率
 *
 *字符串的intern方法（本地方法）
 *调用这个intern方法，会将产生的字符串对象置入常量池(若不存在则置入)
 * 若常量池中已存在该対象，则返回常量中的字符串对象引用!
 *
 */
public class StringTheory {
    public static void main(String[] args) {
//        //此时常量池已经有了“hello”的字符对象，jvm直接将池中对象地址赋值给str1，不在产生新对象
//        String str="hello";
//        String str1="hello";
//        //"HELLO"字符串字面量，每一个字符串字面量都是一个字符串常量，也就是一个字符串的对象
//        String str2=new String("hello");
//        str2=str2.intern();//常量池中已有常量对象
//        System.out.println(str==str1);//true
//        System.out.println(str==str2);//true

//        char []ch=new char[]{'a','b','c'};//堆中开辟空间存放'a','b','c'
//        String s1=new String(ch);//堆中开辟空间存放“abc”
//        String s2="abc";//第一次出现“abc”常量，放入常量池
//        //false
//        System.out.println(s1==s2);

        char []ch=new char[]{'a','b','c'};//堆中开辟空间存放'a','b','c'
        String s1=new String(ch);//堆中开辟空间存放“abc”
        s1.intern();
        String s2="abc";//第一次出现“abc”常量，放入常量池
        //true
        System.out.println(s1==s2);

//        String str="hello";
//        String str1="hello";
//        String str2=new String("hello");
//        str2.intern();//不接收的str2还在指向堆中的“hello“
//        System.out.println(str==str1);//true
//        System.out.println(str==str2);//false
    }
}
